package com.gavin.export.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson2.JSONObject;
import com.gavin.export.model.Users;
import com.gavin.export.model.dto.UserExcelDTO;
import com.gavin.export.service.UserExportExcelService;
import com.gavin.export.service.UsersService;
import com.gavin.export.utils.EasyExcelUtil;
import com.gavin.export.utils.GuoMiSM4Utils;
import com.gavin.export.utils.SignMd5Util;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * UserExportExcelServiceImpl
 *
 * @author grl
 * @date 2024/10/15
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserExportExcelServiceImpl implements UserExportExcelService {

    private final UsersService usersService;

    @Override
    public void exportUserInfo(HttpServletRequest request, HttpServletResponse response, Integer total) {
        exportSimTemplate(request, response, "81t-c用户信息", UserExcelDTO.class, "81t-c用户信息");
    }


    /**
     * 导出通用方法
     *
     * @param request
     * @param response
     * @param filename
     * @param clazz
     * @param sheetName
     */
    private <T extends CellWriteHandler> void exportSimTemplate(HttpServletRequest request, HttpServletResponse response,
                                                                String filename, Class clazz, String sheetName) {
        try {
            filename = URLEncoder.encode(filename, StandardCharsets.UTF_8);
            setHeard(response, filename);
            ExcelWriterBuilder write = EasyExcel.write(response.getOutputStream());

            ExcelWriter excelWriter = write.build();
            WriteSheet writeSheet = EasyExcelUtil.writeSelectedSheet(clazz, 0, sheetName);
            //此处只导出实体类中的数据所以只new 一个空的list，如果想导出数据库数据需要从数据库中查询数据list
            writeData(excelWriter, writeSheet);
            excelWriter.finish();
        } catch (UnsupportedEncodingException e) {
            log.error("导出Excel编码异常", e);
        } catch (IOException e) {
            log.error("导出Excel文件异常", e);
        }
    }

    private void setHeard(HttpServletResponse response, String filename) {
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", String.format("attachment; filename=%s", filename + ".xlsx"));
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", -1);
        response.setCharacterEncoding("UTF-8");
    }

    private void writeData(ExcelWriter excelWriter, WriteSheet writeSheet) {
        Integer pageNumber = 1;
        Integer pageSize = 10000;
        boolean flag = true;
        Page<Users> page = new Page<>(pageNumber, pageSize);
        while (flag) {
            QueryWrapper queryWrapper = QueryWrapper.create().select(
                    Users::getId, Users::getUserNum, Users::getNickName,
                    Users::getAccountLink, Users::getLinkPwd,
                    Users::getProvince,Users::getCity, Users::getDistrict
            ).from(Users.class).orderBy(Users::getId, true);
            Page<Users> pageList = usersService.page(page, queryWrapper);
            List<Users> records = pageList.getRecords();
            List<UserExcelDTO> dtoList = new ArrayList<>(records.size());
            for (int i = 0; i < records.size(); i++) {
                Users users = records.get(i);
                UserExcelDTO convert = convert(users);
                if (convert != null) {
                    dtoList.add(convert);
                }
            }
            excelWriter.write(dtoList, writeSheet);
            if (pageList.hasNext()) {
                long nextPage = page.getPageNumber() + 1;
                page.setPageNumber(nextPage);
            } else {
                flag = false;
            }
        }
    }

    private UserExcelDTO convert(Users user) {
        if (StringUtils.isNotBlank(user.getAccountLink()) && StringUtils.isNotBlank(user.getLinkPwd())) {
            UserExcelDTO dto = new UserExcelDTO();
            JSONObject md5MessageMast = SignMd5Util.getMd5Message(user.getLinkPwd());
            // 解密串
            String decodeMd5 = md5MessageMast.getString("decodeMd5");
            // 手机号
            String phone = GuoMiSM4Utils.decryptEcb(user.getAccountLink(), decodeMd5);
            dto.setAccount(phone);
            dto.setUserNum(user.getUserNum());
            dto.setNickName(user.getNickName());
            dto.setProvince(user.getProvince());
            dto.setCity(user.getCity());
            dto.setDistrict(user.getDistrict());
            dto.setId(user.getId()+"");
            return dto;
        }
        return null;
    }
}
